﻿using Quartz.Core;
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using Autofac;

namespace AutoRegistDependency.Implement
{
    /// <summary>
    ///     Provides additional configuration to Quartz scheduler.
    /// </summary>
    /// <param name="componentContext"></param>
    /// <returns>Quartz configuration settings.</returns>
    public delegate NameValueCollection QuartzConfigurationProvider(IComponentContext componentContext);

    /// <summary>
    ///     Configures scheduler job scope.
    /// </summary>
    /// <remarks>
    ///     Used to override global container registrations at job scope.
    /// </remarks>
    /// <param name="containerBuilder">Autofac container builder.</param>
    /// <param name="scopeTag">Job scope tag.</param>
    public delegate void QuartzJobScopeConfigurator(ContainerBuilder containerBuilder, object scopeTag);
    internal class AutofacSchedulerFactory : StdSchedulerFactory
    {
        readonly AutofacJobFactory _jobFactory;
        /// <summary>
        ///     Initializes a new instance of the <see cref="T:Quartz.Impl.StdSchedulerFactory" /> class.
        /// </summary>
        /// <param name="jobFactory">Job factory.</param>
        /// <exception cref="ArgumentNullException"><paramref name="jobFactory" /> is <see langword="null" />.</exception>
        public AutofacSchedulerFactory(AutofacJobFactory jobFactory)
        {
            _jobFactory = jobFactory ?? throw new ArgumentNullException(nameof(jobFactory));
        }

        /// <summary>
        ///     Initializes a new instance of the <see cref="T:Quartz.Impl.StdSchedulerFactory" /> class.
        /// </summary>
        /// <param name="props">The properties.</param>
        /// <param name="jobFactory">Job factory</param>
        /// <exception cref="ArgumentNullException"><paramref name="jobFactory" /> is <see langword="null" />.</exception>
        public AutofacSchedulerFactory(NameValueCollection props, AutofacJobFactory jobFactory)
            : base(props)
        {
            _jobFactory = jobFactory ?? throw new ArgumentNullException(nameof(jobFactory));
        }

        /// <summary>
        ///     Instantiates the scheduler.
        /// </summary>
        /// <param name="rsrcs">The resources.</param>
        /// <param name="qs">The scheduler.</param>
        /// <returns>Scheduler.</returns>
        protected override IScheduler Instantiate(QuartzSchedulerResources rsrcs, QuartzScheduler qs)
        {
            var scheduler = base.Instantiate(rsrcs, qs);
            scheduler.JobFactory = _jobFactory;
            return scheduler;
        }
    }
}
